<?php
/**
 * Клас модели таблицы в БД. Позволяет загружать структуру таблицы, и сохранять ее в БД, 
 * создавать и удалять таблицы.
 * 
 * @author djerom
 */
class c_table_model extends c_base_model
{
	var $name = ''; // Имя таблицы.
	var $comment = ''; // Описание таблицы.
	var $fields = array(); // Поля таблицы.
	
	var $old_name = '';
	var $old_comment = '';
	var $old_fields = array();

	function c_table_model($name = '')
	{
		if ($name)
			$this->load($name);
	}
	
	// Загрузить описание таблицы.
	function load($name)
	{
		global $mvc;
		$this->name = $name;
		$this->old_name = $this->name;

		$sql = 'SELECT table_comment as comment FROM information_schema.tables
			WHERE table_schema="'.$mvc->config['dbname'].'"
			AND table_name="'.$name.'"';
		$info = $mvc->db->get_data($sql);

		if (sizeof($info) > 0)
		{
			$this->comment = $info[0]['comment'];
			$this->fields = $mvc->db->get_fields($name);
		}
		else
		{
			$this->old_name = '';
			$this->comment = '';
			$this->fields = array();
		}
		
		$this->old_comment = $this->comment;
		$this->old_fields = $this->fields;
	}
	
	// Сохранить описание таблицы.
	function save()
	{	
		if ($this->name == '') return;
	
		global $mvc;
		
		// Если изменили имя таблицы изменилось, то создаем новую таблицу и выходим.
		if ($this->name != $this->old_name)
		{
			if (isset($this->fields['id']))
			{
				$sql = 'CREATE TABLE IF NOT EXISTS '.$this->name.'(id int auto_increment primary key, ';
				unset($this->fields['id']);
			}
			else
				$sql = 'CREATE TABLE '.$this->name.'(';
			
			foreach ($this->fields as $k => $field)
			{
				$sql .= '`'.$field['name'].'` '.$field['type'];
				if (($field['type'] == 'char') || ($field['type'] == 'varchar'))
					$sql .= '('.$field['len'].')';
				$sql .= ' COMMENT "'.$field['comment'].'", ';
			}
			$sql = substr($sql, 0, strlen($sql) - 2).')';
			if ($this->comment) $sql .= ' COMMENT="'.$this->comment.'"';
			
			$mvc->db->query($sql, false);
			
			return;
		}
		
		// Меняем структуру существующей таблицы.		
		// Формируем запрос модификации таблицы (поля, коммент) если нужно. Все модификации выполняются одним запросом.
		$sql = '';

		// 1.Новые поля, 2.измененные поля, 3.удаленные поля. 4. Комментарий.

		// 1,2
		foreach($this->fields as $k => $field)
		{					
			// Поле существует.
			if (isset($this->old_fields[$k]))
			{
				$old_field = $this->old_fields[$k];
				//print_r(array_intersect($field, $old_field));
				//echo '<hr>';
				//die();
				
				// Данные поля не совпали.
				if (sizeof(array_intersect($field, $old_field)) != sizeof($field))
				{					
					$sql .= ' CHANGE `'.$field['name'].'` `'.$field['name'].'` '.$field['type'];
					if (($field['type'] == 'char') || ($field['type'] == 'varchar'))
					{
						$sql .= '('.$field['len'].')';
					}
					$sql .= ' COMMENT "'.$field['comment'].'"';
					$sql .= ',';
				}
			}
			else // Поля нет, добавим его.
			{
				$sql .= ' ADD `'.$field['name'].'` '.$field['type'];
				if (($field['type'] == 'char') || ($field['type'] == 'varchar'))
					$sql .= '('.$field['len'].')';
				$sql .= ' COMMENT "'.$field['comment'].'",';
			}
		}	
		
		
		// 3. Пробегаем по списку старых полей.
		foreach($this->old_fields as $k => $old_field)
		{
			// Старого поля нет в списке новых, значит его надо удалить.
			if (!isset($this->fields[$k]))
			{
				$sql .= ' DROP `'.$k.'`,';
			}
		}			

		// 4. Комментарии.
		if ($this->comment != $this->old_comment)
		{
			$sql .= ' COMMENT="'.$this->comment.'"';
		}
		else
		{
			$sql = substr($sql, 0, strlen($sql) - 1);
		}
		
		if ($sql != '')
		{
			$sql = 'ALTER TABLE '.$this->name.' '.$sql;
			if ($mvc->db->query($sql, false))
			{
				$this->old_name = $this->name;
				$this->old_comment = $this->comment;
				$this->old_fields = $this->fields;
			}
		}
	}
	
	// Добавить поле в описание таблицы. Нужен save() для сохранения.
	function set_field($name, $type, $len = 0, $comment = '')
	{
		$this->fields[$name] = array('name' => $name, 'type' => $type, 'len' => $len, 'comment' => $comment);
		if ($type == 'text') $this->fields[$name]['len'] = 65535;
	}
	
	// Удалить поле из описания таблицы. Нужен save() для сохранения.
	function del_field($name)
	{
		unset($this->fields[$name]);
	}
	
	function delete($name)
	{
		// [DROP TABLE $this->name]
	}
}
?>
